<template>
  <div class="interview-layout">
    <aside class="sidebar">
      <div class="sidebar-header">
        <el-input
          v-model="searchQuery"
          placeholder="搜索面试题..."
          prefix-icon="Search"
          clearable
          size="small"
        />
        <el-button type="primary" @click="handleAdd" size="small" class="add-btn">
          <el-icon><Plus /></el-icon> 新增题目
        </el-button>
      </div>
      <div class="category-list">
        <div v-for="(questions, category) in categorizedQuestions" :key="category" class="category-block">
          <div class="category-title">{{ category }}</div>
          <div>
            <div
              v-for="question in questions"
              :key="question.id"
              class="question-card"
              :class="{ active: currentQuestion?.id === question.id }"
              @click="loadQuestion(question)"
            >
              <div class="card-title-row">
                <span class="card-title">{{ question.title }}</span>
                <span class="card-actions">
                  <el-button size="small" text @click.stop="handleEdit(question)">编辑</el-button>
                  <el-button size="small" text type="danger" @click.stop="handleDelete(question)">删除</el-button>
                </span>
              </div>
              <div class="card-tags">
                <el-tag
                  v-for="tag in question.tags"
                  :key="tag"
                  size="small"
                  class="tag"
                >
                  {{ tag }}
                </el-tag>
              </div>
            </div>
          </div>
        </div>
      </div>
    </aside>
    <main class="main-content">
      <div class="fixed-actions-bar">
        <el-button type="primary" @click="runCode" :disabled="!currentQuestion">
          <el-icon><VideoPlay /></el-icon> 运行代码
        </el-button>
        <el-button @click="copyCode" :disabled="!currentQuestion">
          <el-icon><Document /></el-icon> 复制代码
        </el-button>
      </div>
      <div v-if="currentQuestion" class="question-detail">
        <div class="question-header">
          <h2>{{ currentQuestion?.title }}</h2>
        </div>
        <el-divider />
        <div class="question-section">
          <h3>题目描述</h3>
          <div v-html="currentQuestion?.description"></div>
        </div>
        <div class="question-section">
          <h3>示例代码</h3>
          <div class="code-editor">
            <pre><code ref="codeBlock" class="javascript"></code></pre>
          </div>
        </div>
        <div class="question-section">
          <h3>运行结果</h3>
          <div class="output-panel">
            <div class="output-header">
              <span>控制台输出</span>
              <el-button size="small" @click="clearOutput">
                <el-icon><Delete /></el-icon> 清除
              </el-button>
            </div>
            <div ref="consoleOutput" class="console-output"></div>
          </div>
        </div>
        <div class="question-section">
          <h3>解析</h3>
          <div v-html="currentQuestion?.analysis"></div>
        </div>
      </div>
      <div v-else class="empty-detail">
        <el-empty description="请选择一道面试题" />
      </div>
    </main>
    <!-- 新增/编辑题目弹窗 -->
    <el-dialog v-model="dialogVisible" :title="editMode ? '编辑面试题' : '新增面试题'" width="600px">
      <el-form :model="form" label-width="80px" size="small">
        <el-form-item label="标题">
          <el-input v-model="form.title" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input type="textarea" v-model="form.description" />
        </el-form-item>
        <el-form-item label="分类">
          <el-input v-model="form.category" />
        </el-form-item>
        <el-form-item label="标签">
          <el-select v-model="form.tags" multiple placeholder="请选择标签">
            <el-option v-for="tag in ['JS','Vue','算法','网络','手写']" :key="tag" :label="tag" :value="tag" />
          </el-select>
        </el-form-item>
        <el-form-item label="代码">
          <el-input type="textarea" v-model="form.code" :rows="8" />
        </el-form-item>
        <el-form-item label="解析">
          <el-input type="textarea" v-model="form.analysis" :rows="3" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { VideoPlay, Document, Delete, Search, Plus } from '@element-plus/icons-vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'
import { reactive } from 'vue'

const searchQuery = ref('')
const currentQuestion = ref(null)
const codeBlock = ref(null)
const consoleOutput = ref(null)
const dialogVisible = ref(false)
const editMode = ref(false)
const form = ref({
  title: '',
  description: '',
  category: '',
  tags: [],
  code: '',
  analysis: ''
})
const editingId = ref(null)
const questions = ref({})

const categorizedQuestions = computed(() => {
  const filtered = Object.entries(questions.value).reduce((acc, [category, questionList]) => {
    const filteredList = questionList.filter(q => {
      return (
        searchQuery.value === '' ||
        q.title.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
        (q.tags && q.tags.some(tag => tag.toLowerCase().includes(searchQuery.value.toLowerCase())))
      )
    })
    if (filteredList.length > 0) {
      acc[category] = filteredList
    }
    return acc
  }, {})
  return filtered
})

// 应用代码高亮
const applyHighlight = () => {
  if (!codeBlock.value || !currentQuestion.value) return
  
  const code = currentQuestion.value.code.trim()
  const highlighted = hljs.highlight(code, { language: 'javascript' }).value
  codeBlock.value.innerHTML = highlighted
}

// 加载问题
const loadQuestion = async (question) => {
  currentQuestion.value = question
  await nextTick()
  applyHighlight()
}

// 运行代码
const runCode = () => {
  if (!currentQuestion.value) return

  const code = currentQuestion.value.code.trim()
  consoleOutput.value.innerHTML = ''

  const originalConsoleLog = console.log
  try {
    console.log = (...args) => {
      consoleOutput.value.innerHTML += args.join(' ') + '\n'
      originalConsoleLog.apply(console, args)
    }
    eval(code)
  } catch (error) {
    consoleOutput.value.innerHTML = `Error: ${error.message}`
  } finally {
    console.log = originalConsoleLog
  }
}

// 复制代码
const copyCode = async () => {
  if (!currentQuestion.value) return
  
  try {
    await navigator.clipboard.writeText(currentQuestion.value.code.trim())
    ElMessage.success('代码已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 清除输出
const clearOutput = () => {
  if (consoleOutput.value) {
    consoleOutput.value.innerHTML = ''
  }
}

// 监听代码块变化
watch(() => currentQuestion.value?.code, () => {
  nextTick(applyHighlight)
})

// 监听代码块元素变化
watch(codeBlock, (newVal) => {
  if (newVal && currentQuestion.value) {
    nextTick(applyHighlight)
  }
})

// 拉取题库
const fetchQuestions = async () => {
  const res = await fetch('/api/interview/questions')
  const data = await res.json()
  questions.value = data.questions || {}
  // 自动加载第一个问题
  const firstCategory = Object.keys(questions.value)[0]
  if (firstCategory && questions.value[firstCategory].length > 0) {
    loadQuestion(questions.value[firstCategory][0])
  } else {
    currentQuestion.value = null
  }
}

onMounted(() => {
  fetchQuestions()
})

const handleAdd = () => {
  editMode.value = false
  editingId.value = null
  form.value = { title: '', description: '', category: '', tags: [], code: '', analysis: '' }
  dialogVisible.value = true
}
const handleEdit = (question) => {
  editMode.value = true
  editingId.value = question.id
  form.value = { ...question }
  dialogVisible.value = true
}
const handleDelete = (question) => {
  ElMessageBox.confirm('确定要删除该面试题吗？', '提示', { type: 'warning' })
    .then(async () => {
      await fetch(`/api/interview/questions/${question.id}`, { method: 'DELETE' })
      ElMessage.success('删除成功')
      fetchQuestions()
    })
    .catch(() => {})
}
const submitForm = async () => {
  if (editMode.value) {
    await fetch(`/api/interview/questions/${editingId.value}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(form.value)
    })
    ElMessage.success('编辑成功')
  } else {
    await fetch('/api/interview/questions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(form.value)
    })
    ElMessage.success('新增成功')
  }
  dialogVisible.value = false
  fetchQuestions()
}
</script>

<style scoped>
html, body, #app {
  height: 100%;
  margin: 0;
  padding: 0;
}
.interview-layout {
  width: 90vw;
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  height: 100%;
}
.sidebar {
  width: 340px;
  background: #fff;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.sidebar-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 20px 20px 10px 20px;
}
.add-btn {
  margin-left: auto;
}
.category-list {
  flex: 1;
  overflow-y: auto;
  padding: 10px 20px 20px 20px;
}
.category-block {
  margin-bottom: 24px;
}
.category-title {
  font-size: 16px;
  font-weight: bold;
  color: #409EFF;
  margin-bottom: 10px;
  border-left: 4px solid #409EFF;
  padding-left: 8px;
}
.question-card {
  background: #f8fafd;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.04);
  margin-bottom: 10px;
  padding: 12px 16px;
  cursor: pointer;
  border: 1px solid #ebeef5;
  transition: box-shadow 0.2s, border 0.2s;
}
.question-card.active {
  border: 1.5px solid #409EFF;
  background: #eaf6ff;
  box-shadow: 0 2px 8px rgba(64,158,255,0.08);
}
.card-title-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.card-title {
  font-size: 15px;
  font-weight: 500;
  color: #303133;
}
.card-actions {
  display: flex;
  gap: 4px;
}
.card-tags {
  margin-top: 6px;
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.main-content {
  flex: 1 1 0;
  /* min-height: 0; */
  padding: 0px 40px 20px 40px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.fixed-actions-bar {
  background: #fff;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0;
  margin-bottom: 24px;
}
.question-detail {
  background: #fff;
  border-radius: 10px;
  /* box-shadow: 0 2px 12px 0 rgba(0,0,0,0.06); */
  padding: 56px 36px 32px 36px;
  min-height: 0;
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
}
.question-header {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}
.question-header h2 {
  font-size: 22px;
  color: #303133;
  margin: 0;
}
.question-section {
  margin-bottom: 32px;
}
.question-section h3 {
  font-size: 16px;
  color: #409EFF;
  margin-bottom: 10px;
  font-weight: 500;
}
.code-editor {
  background: #0d1117;
  border-radius: 6px;
  padding: 16px;
  margin: 12px 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  color: #c9d1d9;
  font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
  font-size: 14px;
}
.code-editor pre {
  margin: 0;
  padding: 0;
  background: transparent !important;
}
.output-panel {
  background: #f5f7fa;
  border-radius: 6px;
  padding: 16px;
}
.output-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  color: #606266;
}
.console-output {
  background: #1e1e1e;
  color: #d4d4d4;
  padding: 16px;
  border-radius: 6px;
  font-family: 'Fira Code', monospace;
  font-size: 14px;
  line-height: 1.6;
  min-height: 100px;
  max-height: 300px;
  overflow-y: auto;
  white-space: pre-wrap;
}
.empty-detail {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
</style> 